package se.webbzon.boltzmann.battle.strategy.playerstrategy;

import java.awt.Color;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import se.webbzon.boltzmann.battle.battleaction.BattleAction;
import se.webbzon.boltzmann.battle.battleaction.BattleActionFactory;
import se.webbzon.boltzmann.battle.group.BattleGroup;
import se.webbzon.boltzmann.battle.object.npc.BattleNPC;
import se.webbzon.boltzmann.collector.Collector;
import se.webbzon.boltzmann.effect.Effect;
import se.webbzon.boltzmann.effect.MarkerEffect;
import se.webbzon.boltzmann.game.object.camera.GameCamera;
import se.webbzon.boltzmann.input.Button;
import se.webbzon.oschi01.worldarea.WorldArea;
import se.webbzon.oschi01.worldcamera.WorldCameraPane;
import se.webbzon.oschi01.worldcamera.WorldView;

public class PSTargetPage extends AbstractPSPage {
	
	// A collection of all the markers
	private final Collection<Effect> markerEffects;
	
	// The battle action factory associated with this target page
	private final BattleActionFactory factory;
	
	// The game camera associated with the player associated 
	// with this target page 
	private final GameCamera camera;
	
	// The number of available targets
	private final int targets;
	
	// The index of the current target
	private int targetIndex;
	
	// The current target
	private List<BattleNPC> target;
	
	/*============================================================
	Constructors
	============================================================*/
	
	/** Creates a new player strategy target page. **/
	public PSTargetPage(AbstractPSPage parent,
						BattleActionFactory factory, 
						PlayerStrategyHud psh) {
		super(parent);
		this.factory = factory;
		
		// Retrieve game camera
		Collector<GameCamera> cameraCollector = 
				Collector.getCollector(psh.getWorld(), GameCamera.class);
		GameCamera c = null;
		OUTER : for (GameCamera camera : cameraCollector.getInstances()) {
			Collection<WorldView> views = camera.getViews();
			synchronized (views) {
				for (WorldView view : views) {
					if (psh.getStrategy().getPlayer().getView() == view) {
						c = camera;
						break OUTER;
					}
				}
			}
		}
		camera = c;
		
		final PlayerStrategy strategy = psh.getStrategy();
		
		BattleNPC caster = strategy.getCaster();
		List<BattleGroup> all = strategy.getBattleGroups();
		
		markerEffects = new ArrayList<Effect>();
		targets = factory.targets(all,caster);
		targetIndex = 0;
		setTarget(psh,targetIndex);
	}
	
	/*============================================================
	Public Methods
	============================================================*/

	@Override public void onSelect(PlayerStrategyHud psh) {
		final PlayerStrategy strategy = psh.getStrategy();
		BattleAction battleAction = 
				factory.makeBattleAction(	psh.getWorld(), 
											strategy.getCaster(), target);
		strategy.notifyListeners(battleAction);
		battleAction.start();
		
		// Move camera to back to caster
		camera.setTarget(strategy.getCaster());
		
		// Destroy the markers
		for (Effect effect : markerEffects)
			effect.terminate(psh.getWorld());
		markerEffects.clear();
		
		// Destroy the heads-up display
		psh.getWorld().destroyInstance(psh);
	}

	@Override public void onReturn(PlayerStrategyHud psh) {
		psh.setPage(getParent());
	}

	@Override public void onPress(PlayerStrategyHud psh, Button button) {
		if (button == Button.LEFT) {
			if (targetIndex == 0)
				targetIndex = targets-1;
			else
				targetIndex--;
			setTarget(psh,targetIndex);
		} else if (button == Button.RIGHT) {
			if (targetIndex == targets-1)
				targetIndex = 0;
			else
				targetIndex++;
			setTarget(psh,targetIndex);
		}
	}

	@Override public void onStep(PlayerStrategyHud psh) {};

	@Override public void onDraw(PlayerStrategyHud psh, WorldCameraPane hud) {};
	
	/*============================================================
	Private Methods
	============================================================*/
	
	/** Sets the target of this strategy to the (n+1):th available in
	 * the provided battle action factory.  **/
	private void setTarget(PlayerStrategyHud psh, int n) {
		final PlayerStrategy strategy = psh.getStrategy();
		final WorldArea world = psh.getWorld();
		List<BattleNPC> target = 
				factory.getTarget(	strategy.getBattleGroups(), 
									strategy.getCaster(), n);
		
		// Remove old markers
		for (Effect effect : markerEffects)
			effect.terminate(world);
		markerEffects.clear();
		
		// Add new markers
		for (BattleNPC npc : target) {
			MarkerEffect marker = new MarkerEffect(npc,Color.red);
			markerEffects.add(marker);
			marker.launch(world);
		}
		
		// Move camera to target
		camera.setTarget(target.get(0));
		
		this.target = target;
	}

}
